package common

import (
	"douhu_backend/internal/config"
	logger "douhu_backend/internal/log"
	"fmt"
	"strings"

	"github.com/kataras/iris/v12"
)

// CORSConfig CORS配置结构
type CORSConfig struct {
	// 允许的源地址，* 表示允许所有
	AllowedOrigins []string
	// 允许的HTTP方法
	AllowedMethods []string
	// 允许的请求头
	AllowedHeaders []string
	// 是否允许发送凭证（cookies等）
	AllowCredentials bool
	// 预检请求的缓存时间（秒）
	MaxAge int
}

// CORSService CORS服务
type CORSService struct {
	config *CORSConfig
}

// NewCORSService 创建CORS服务
func NewCORSService(cfg *CORSConfig) *CORSService {
	if cfg == nil {
		cfg = &CORSConfig{
			AllowedOrigins: []string{"*"},
			AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
			AllowedHeaders: []string{
				"Origin", "Content-Type", "Accept", "Authorization",
				"X-Requested-With", "X-Request-ID", "X-Client-Version",
			},
			AllowCredentials: false,
			MaxAge:           86400, // 24小时
		}
	}
	return &CORSService{config: cfg}
}

// NewDefaultCORSService 创建默认CORS服务
func NewDefaultCORSService() *CORSService {
	return NewCORSService(nil)
}

// NewDevelopmentCORSService 创建开发环境CORS服务
func NewDevelopmentCORSService() *CORSService {
	cfg := &CORSConfig{
		AllowedOrigins: []string{
			"http://localhost:3000",
			"http://localhost:3010",
			"http://localhost:3012",
			"http://127.0.0.1:3000",
			"http://127.0.0.1:3010",
			"http://127.0.0.1:3012",
			"http://127.0.0.1:8000",
			"http://127.94.0.1:3010",
			"http://192.168.30.112:3010",
			"http://172.16.0.2:3010",
			"http://10.37.129.2:3010",
			"http://192.168.64.1:3010",
		},
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
		AllowedHeaders: []string{
			"Origin", "Content-Type", "Accept", "Authorization",
			"X-Requested-With", "X-Request-ID", "X-Client-Version",
		},
		AllowCredentials: true,
		MaxAge:           3600, // 1小时
	}
	return NewCORSService(cfg)
}

// NewProductionCORSService 创建生产环境CORS服务
func NewProductionCORSService(allowedDomains []string) *CORSService {
	cfg := &CORSConfig{
		AllowedOrigins: allowedDomains,
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders: []string{
			"Origin", "Content-Type", "Accept", "Authorization", "X-Requested-With",
		},
		AllowCredentials: true,
		MaxAge:           86400, // 24小时
	}
	return NewCORSService(cfg)
}

// NewCORSServiceFromConfig 从应用配置创建CORS服务
func NewCORSServiceFromConfig() *CORSService {
	// 如果配置中没有启用CORS，返回默认配置
	if config.Conf.CORS == nil || !config.Conf.CORS.Enabled {
		return NewDefaultCORSService()
	}

	cfg := &CORSConfig{
		AllowedOrigins:   config.Conf.CORS.AllowedOrigins,
		AllowedMethods:   config.Conf.CORS.AllowedMethods,
		AllowedHeaders:   config.Conf.CORS.AllowedHeaders,
		AllowCredentials: config.Conf.CORS.AllowCredentials,
		MaxAge:           config.Conf.CORS.MaxAge,
	}

	// 如果配置为空，使用默认值
	if len(cfg.AllowedOrigins) == 0 {
		cfg.AllowedOrigins = []string{"*"}
	}
	if len(cfg.AllowedMethods) == 0 {
		cfg.AllowedMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}
	}
	if len(cfg.AllowedHeaders) == 0 {
		cfg.AllowedHeaders = []string{
			"Origin", "Content-Type", "Accept", "Authorization", "X-Requested-With",
		}
	}
	if cfg.MaxAge == 0 {
		cfg.MaxAge = 86400
	}

	return NewCORSService(cfg)
}

// Middleware 创建CORS中间件
func (s *CORSService) Middleware() iris.Handler {
	return func(ctx iris.Context) {
		origin := ctx.GetHeader("Origin")
		method := ctx.Method()
		path := ctx.Path()

		// 调试日志
		if config.Conf.App != nil && config.Conf.App.Debug {
			logger.L.Debugf("CORS: %s %s from origin: %s", method, path, origin)
		}

		// 检查来源是否被允许
		if origin != "" && !s.isOriginAllowed(origin) {
			if config.Conf.App != nil && config.Conf.App.Debug {
				logger.L.Debugf("CORS: Origin %s not allowed", origin)
			}
			ctx.StatusCode(403)
			ctx.JSON(map[string]string{"error": "CORS: origin not allowed"})
			return
		}

		// 设置基本的 CORS 头部
		ctx.Header("Access-Control-Allow-Origin", s.getOriginHeader(origin))

		// 设置允许的方法
		if len(s.config.AllowedMethods) > 0 {
			ctx.Header("Access-Control-Allow-Methods", strings.Join(s.config.AllowedMethods, ", "))
		}

		// 设置允许的头部
		if len(s.config.AllowedHeaders) > 0 {
			ctx.Header("Access-Control-Allow-Headers", strings.Join(s.config.AllowedHeaders, ", "))
		}

		// 设置是否允许凭证
		if s.config.AllowCredentials {
			ctx.Header("Access-Control-Allow-Credentials", "true")
		}

		// 设置预检请求缓存时间
		if s.config.MaxAge > 0 {
			ctx.Header("Access-Control-Max-Age", fmt.Sprintf("%d", s.config.MaxAge))
		}

		// 处理预检请求（OPTIONS）
		if method == "OPTIONS" {
			if config.Conf.App != nil && config.Conf.App.Debug {
				logger.L.Debugf("CORS: Handling preflight request for %s", path)
			}

			// 检查请求的方法是否被允许
			requestMethod := ctx.GetHeader("Access-Control-Request-Method")
			if requestMethod != "" {
				if !s.contains(s.config.AllowedMethods, requestMethod) {
					if config.Conf.App != nil && config.Conf.App.Debug {
						logger.L.Debugf("CORS: Method %s not allowed", requestMethod)
					}
					ctx.StatusCode(405) // Method Not Allowed
					return
				}
			}

			// 检查请求的头部是否被允许
			requestHeaders := ctx.GetHeader("Access-Control-Request-Headers")
			if requestHeaders != "" {
				headers := strings.Split(requestHeaders, ",")
				for _, header := range headers {
					header = strings.TrimSpace(header)
					if !s.isHeaderAllowed(header) {
						if config.Conf.App != nil && config.Conf.App.Debug {
							logger.L.Debugf("CORS: Header %s not allowed", header)
						}
						ctx.StatusCode(400) // Bad Request
						return
					}
				}
			}

			if config.Conf.App != nil && config.Conf.App.Debug {
				logger.L.Debugf("CORS: Preflight request approved for %s", path)
			}
			ctx.StatusCode(204) // No Content
			return
		}

		// 继续处理非预检请求
		ctx.Next()
	}
}

// SimpleMiddleware 创建简单的CORS中间件（用于快速调试）
func (s *CORSService) SimpleMiddleware() iris.Handler {
	return func(ctx iris.Context) {
		origin := ctx.GetHeader("Origin")
		method := ctx.Method()
		path := ctx.Path()

		logger.L.Infof("CORS: Processing %s %s from origin: %s", method, path, origin)

		// 设置宽松的CORS头部，用于调试
		if origin != "" {
			ctx.Header("Access-Control-Allow-Origin", origin)
		} else {
			ctx.Header("Access-Control-Allow-Origin", "*")
		}

		// 设置所有必要的CORS头部
		ctx.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD")
		ctx.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization, X-Requested-With, X-Request-ID, X-Client-Version, Cache-Control, Pragma")
		ctx.Header("Access-Control-Allow-Credentials", "true")
		ctx.Header("Access-Control-Max-Age", "86400")
		ctx.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")

		// 处理预检请求
		if method == "OPTIONS" {
			logger.L.Infof("CORS: Handling OPTIONS preflight for %s from %s", path, origin)
			ctx.StatusCode(204)
			return
		}

		logger.L.Infof("CORS: Allowing %s request to %s from %s", method, path, origin)
		ctx.Next()
	}
}

// ForceAllowMiddleware 创建强制允许所有跨域请求的中间件（开发调试用）
func (s *CORSService) ForceAllowMiddleware() iris.Handler {
	return func(ctx iris.Context) {
		// 无条件设置最宽松的CORS头部
		ctx.Header("Access-Control-Allow-Origin", "*")
		ctx.Header("Access-Control-Allow-Methods", "*")
		ctx.Header("Access-Control-Allow-Headers", "*")
		ctx.Header("Access-Control-Allow-Credentials", "true")
		ctx.Header("Access-Control-Max-Age", "86400")
		ctx.Header("Access-Control-Expose-Headers", "*")

		method := ctx.Method()
		if method == "OPTIONS" {
			logger.L.Infof("CORS: Force allowing OPTIONS preflight for %s", ctx.Path())
			ctx.StatusCode(200) // 使用200而不是204，有些浏览器对204有问题
			ctx.WriteString("OK")
			return
		}

		logger.L.Infof("CORS: Force allowing %s request to %s", method, ctx.Path())
		ctx.Next()
	}
}

// ApplyToApp 将CORS中间件应用到整个应用
func (s *CORSService) ApplyToApp(app *iris.Application) {
	app.Use(s.Middleware())
}

// ApplyToParty 将CORS中间件应用到路由组
func (s *CORSService) ApplyToParty(party iris.Party) {
	party.Use(s.Middleware())
}

// isOriginAllowed 检查源是否被允许（私有方法）
func (s *CORSService) isOriginAllowed(origin string) bool {
	if len(s.config.AllowedOrigins) == 0 {
		return false
	}

	for _, allowedOrigin := range s.config.AllowedOrigins {
		if allowedOrigin == "*" {
			return true
		}
		if allowedOrigin == origin {
			return true
		}
		// 支持通配符匹配
		if strings.HasSuffix(allowedOrigin, "*") {
			prefix := strings.TrimSuffix(allowedOrigin, "*")
			if strings.HasPrefix(origin, prefix) {
				return true
			}
		}
	}

	return false
}

// getOriginHeader 获取Origin头的值（私有方法）
func (s *CORSService) getOriginHeader(origin string) string {
	// 如果允许所有源
	for _, allowedOrigin := range s.config.AllowedOrigins {
		if allowedOrigin == "*" {
			return "*"
		}
	}
	// 返回具体的源，如果没有 origin 则返回第一个允许的源
	if origin != "" {
		return origin
	}
	if len(s.config.AllowedOrigins) > 0 {
		return s.config.AllowedOrigins[0]
	}
	return "*"
}

// isHeaderAllowed 检查头部是否被允许（私有方法）
func (s *CORSService) isHeaderAllowed(header string) bool {
	// 默认允许的简单头部
	simpleHeaders := []string{
		"accept",
		"accept-language",
		"content-language",
		"content-type",
	}

	header = strings.ToLower(header)

	// 检查是否是简单头部
	for _, simple := range simpleHeaders {
		if header == simple {
			return true
		}
	}

	// 检查是否在允许列表中
	for _, allowed := range s.config.AllowedHeaders {
		if strings.ToLower(allowed) == header {
			return true
		}
	}

	return false
}

// contains 检查字符串切片是否包含特定值（私有方法）
func (s *CORSService) contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

// GetConfig 获取当前CORS配置
func (s *CORSService) GetConfig() *CORSConfig {
	return s.config
}

// UpdateConfig 更新CORS配置
func (s *CORSService) UpdateConfig(cfg *CORSConfig) {
	if cfg != nil {
		s.config = cfg
	}
}
